package com.youbug.system.schedule;

import com.youbug.system.entity.Job;
import com.youbug.system.entity.JobExecHis;
import com.youbug.system.service.IJobExecHisService;
import com.youbug.system.service.IJobService;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.ObjectUtils;

@Slf4j
public abstract class AbstractJob implements BeanNameAware, ApplicationContextAware {

    public AbstractJob() {

    }
    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        this.jobService = context.getBean(IJobService.class);
        this.jobExecHisService = context.getBean(IJobExecHisService.class);
    }

    private IJobService jobService;
    private IJobExecHisService jobExecHisService;
    private ThreadLocal<Integer> hisId = new ThreadLocal<>();

    private boolean executing = false;

    private String jobCode;

    private String EXECUTING = "0";
    private String DONE = "1";
    private String ERROR = "2";

    protected boolean start(boolean auto){
        this.setExecuting();

        Job jobEntity = jobService.getJobByCode(jobCode);

        if(ObjectUtils.isEmpty(jobEntity)){
            log.error(jobCode + "任务未配置");
            return false;
        }

        JobExecHis jobExecHis = new JobExecHis();
        jobExecHis.setJobCode(jobCode);
        jobExecHis.setJobName(jobEntity.getName());
        jobExecHis.setStatus(EXECUTING);
        boolean save = jobExecHisService.save(jobExecHis);

        hisId.set(jobExecHis.getId());

        return true;
    }

    public abstract void exec();

    void end(boolean isError){
        this.executing = false;
        Integer id = hisId.get();
        JobExecHis jobExecHis = new JobExecHis();
        jobExecHis.setId(id);
        jobExecHis.setStatus(isError ? ERROR : DONE);
        jobExecHisService.updateById(jobExecHis);
    }

    public boolean getExecuting(){
        return this.executing;
    }

    private void setExecuting(){
        this.executing = true;
    }

    @Override
    public void setBeanName(String beanName) {
        this.jobCode = beanName;
    }
}
